﻿/******************************************************************************
Module:  Exception.cs
Notices: Copyright (c) 2006-2007 by Jeffrey Richter and Wintellect
******************************************************************************/


using System;
using System.Runtime.Serialization;


///////////////////////////////////////////////////////////////////////////////


[Serializable]
public class ExceptionArgs
{
}


///////////////////////////////////////////////////////////////////////////////


[Serializable]
public sealed class Exception<T> : Exception, ISerializable where T : ExceptionArgs
{
    // The three public constructors
    public Exception() : this(null) { }
    public Exception(String message)
        : this(message, null)
    {
    }
    public Exception(String message, Exception innerException)
        : this(null, message, innerException)
    {
    }

    private const String c_args = "Args";
    private readonly T m_args;
    public T Args { get { return m_args; } }    

    // The fourth public constructor because there is a field
    public Exception(T args, String message, Exception innerException)
        : base(message, innerException)
    {
        m_args = args;
    }
    public Exception(T args, String message)
        : this(args, message, null)
    {
    }

    // Because at least 1 field is defined, 
    // define the special deserialization constructor
    // Since this class is sealed, this constructor is private
    // If this class were not sealed, this constructor should be protected
    private Exception(SerializationInfo info, StreamingContext context)
        : base(info, context) // Let the base deserialize its fields
    {
        // Deserialize each field
        m_args = (T)info.GetValue(c_args, typeof(T));
    }

    // Because at least 1 field is defined, 
    // define the serialization method
    public override void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        // Serialize each field
        info.AddValue(c_args, m_args);

        // Let the base type serialize its fields
        base.GetObjectData(info, context);
    }

    public override string Message
    {
        get
        {
            return base.Message + ((m_args != null) ? m_args.ToString() : null);
        }
    }
    public override string ToString()
    {
        return base.ToString();
    }
    public override int GetHashCode()
    {
        return base.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        Exception<T> other = obj as Exception<T>;
        if (obj == null) return false;
        return Object.Equals(m_args, other.m_args) && base.Equals(obj);
    }
}


//////////////////////////////// End of File //////////////////////////////////